#region Using directives

using System;
using System.Collections.Generic;
using System.Text;

#endregion

namespace Weazel.Gezel.Model
{

  public partial class OutPort : Port, ISignalEntity, ITypedEntity
  {
    internal Signal source;

    public Signal Source
    {
      get
      {
        return source;
      }
      set
      {
        source = value;
      }
    }

		/// <summary>
		/// If the outport is connected to an outport of a
		/// nested datapath or ipblock, this field stores a reference
		/// to the outport instance.
		/// </summary>
		private OutPort outportDriver = null;
		public OutPort OutportDriver
		{
			get
			{
				return outportDriver;
			}
			internal set
			{
				outportDriver = value;
			}
		}

    /// <summary>
    /// The list of expressions which can drive
    /// this entity during simulation. The
    /// list is not populated before the
    /// verification has completed.
    /// </summary>
    private List<Expression> definers;
    public List<Expression> Definers
    {
      get
      {
        return definers;
      }
    }

    /// <summary>
    /// Maps each definer of this entity to the signalflowgraph
    /// in which the definer is active.
    /// </summary>
    private Dictionary<Expression, SignalFlowGraph> definingSignalFlowGraphs;
    public Dictionary<Expression, SignalFlowGraph> DefiningSignalFlowGraphs
    {
      get
      {
        return definingSignalFlowGraphs;
      }
    }



    public OutPort(IPBlock parent, string name, int width, bool signed, int pos) : 
      base(parent, name, width, signed, pos)
    {
      this.definers = new List<Expression>();
      this.definingSignalFlowGraphs = new Dictionary<Expression, SignalFlowGraph>();
    }

		public OutPort(
			IPBlock parent, 
			string name, 
			int width, 
			bool signed, 
			int pos,
			Position startPosition,
			Position endPosition
		)
			: base(parent, name, width, signed, pos, startPosition, endPosition)
    {
      this.definers = new List<Expression>();
      this.definingSignalFlowGraphs = new Dictionary<Expression, SignalFlowGraph>();
    }

		protected OutPort(Datapath parent, string name)
			: base(parent, name, -1)
		{
			this.definers = new List<Expression>();
			this.definingSignalFlowGraphs = new Dictionary<Expression, SignalFlowGraph>();
		}

		protected OutPort(IPBlock parent, string name)
			: base(parent, name, -1)
		{
			this.definers = new List<Expression>();
			this.definingSignalFlowGraphs = new Dictionary<Expression, SignalFlowGraph>();
		}

    public OutPort(Datapath parent, string name, int width, bool signed, int pos) : 
      base(parent, name, width, signed, pos)
    {
      this.definers = new List<Expression>();
      this.definingSignalFlowGraphs = new Dictionary<Expression, SignalFlowGraph>();
    }

		public OutPort(
			Datapath parent, 
			string name, 
			int width, 
			bool signed, 
			int pos, 
			Position startPosition,
			Position endPosition
		)
			: base(parent, name, width, signed, pos, startPosition, endPosition)
    {
      this.definers = new List<Expression>();
      this.definingSignalFlowGraphs = new Dictionary<Expression, SignalFlowGraph>();
    }

    public OutPort Clone(IPBlock newParent)
    {
      OutPort clone = new OutPort(newParent, localName, Width, Signed, DeclarationPosition, startPosition, endPosition);
      clone.source = this.source.Clone(clone);
      return clone;
    }

    public OutPort Clone(Datapath newParent)
    {
      OutPort clone = new OutPort(newParent, localName, Width, Signed, DeclarationPosition, startPosition, endPosition);
      if(source != null)
        clone.source = this.source.Clone(clone);
      return clone;
    }
  }
}
